﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using sqengine.Engine.Common;
using SqEngine;




namespace sqengine.Components
{


    public class SaveManager
    {
        private WeaponInfo _wpinfo;
        private BotInfo _botinfo;
        private CfgSave _cfgsave;
        private MapObject _mapobj;
        private BasicWorldObject _basicwo;
        private IntroContent _introcontent;
        private MediaPlayerPlaylist _mediaplayerpl;
        private GameVars _gamevars;

        public SaveManager()
        {
            _wpinfo = new WeaponInfo();
            _botinfo = new BotInfo();
            _cfgsave = new CfgSave();
            _basicwo = new BasicWorldObject();
            _introcontent = new IntroContent();
            _mediaplayerpl = new MediaPlayerPlaylist();
            _gamevars = new GameVars();
            _mapobj = new MapObject();
        }


        #region Custom Serialize/Deserialize functions

        public object Deserialize(Stream st, Type type)
        {
            return Deserialize(st, type, 0);
        }

        public object Deserialize(Stream st, Type type, int format_type)
        {
            if (format_type == 0)
            {
                XmlSerializer xs = new XmlSerializer(type);
                st = Functions.DecompressStream(st);
                return (object)xs.Deserialize(st);
            }
            else
            {
                BinaryFormatter bf = new BinaryFormatter();
                return (object)(bf.Deserialize(st));

            }


        }
        public void Serialize(FileStream st, Type type, object obj)
        {
            Serialize(st, type, obj, 0);
        }

        public void Serialize(FileStream st, Type type, object obj, int format_type)
        {
            if (format_type == 0)
            {
                string fn = st.Name;
                XmlSerializer xs = new XmlSerializer(type);                    
                xs.Serialize(st, obj);
                MemoryStream tmp = Functions.CompressStream(st);
                st.Flush();
                st.Close();
                Functions.SaveMemoryStream(tmp, fn);
                
            }
            else
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(st, obj);
            }

        }
        #endregion

        #region Weapon
        public WeaponInfo LoadWeapon(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _wpinfo = (WeaponInfo)(Deserialize(fs, _wpinfo.GetType()));
            fs.Close();

            return _wpinfo;
        }

        public void SaveWeapon(string filename, WeaponInfo weapon)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs, weapon.GetType(), weapon);
            fs.Close();
        }
        #endregion

        #region Configuration
        public CfgSave LoadConfig(string filename)
        {

            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _cfgsave = (CfgSave)Deserialize(fs, _cfgsave.GetType());
            fs.Close();

            return _cfgsave;
        }

        public void SaveConfig(string filename, CfgSave cfg)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);           
            Serialize(fs, cfg.GetType(), cfg);
            fs.Close();
        }
        #endregion

        #region IntroContent

        public IntroContent LoadIntro(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _introcontent = (IntroContent)(Deserialize(fs, _introcontent.GetType()));
            fs.Close();

            return _introcontent;
        }


        public void SaveIntro(string filename, IntroContent introcontent)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs, introcontent.GetType(), introcontent);
            fs.Close();
        }


        #endregion

        #region Bot
        public BotInfo LoadBot(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _botinfo = (BotInfo)Deserialize(fs, _botinfo.GetType());
            fs.Close();

            return _botinfo;
        }

        public void SaveBot(string filename, BotInfo bot)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs, bot.GetType(), bot);
            fs.Close();
        }
        #endregion

        #region BasicWorldObject

        public BasicWorldObject LoadBasicWorldObject(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _basicwo = (BasicWorldObject)Deserialize(fs, _basicwo.GetType());
            fs.Close();

            return _basicwo;
        }

        public void SaveBasicWorldObject(string filename, BasicWorldObject bwo)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs, bwo.GetType(), bwo);
            fs.Close();
        }


        #endregion

        #region Map
        public MapObject LoadMap(string filename)
        {

            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _mapobj = (MapObject)(Deserialize(fs, _mapobj.GetType(),1));
            fs.Close();

            return _mapobj;
        }


        public void SaveMap(string filename, MapObject mapobj)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs, mapobj.GetType(), mapobj,1);
            fs.Close();
        }


        #endregion

        #region MediaPlayerPlaylist

        public MediaPlayerPlaylist LoadMediaPlayerPlaylist(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            _mediaplayerpl = (MediaPlayerPlaylist)Deserialize(fs,_mediaplayerpl.GetType());
            fs.Close();

            return _mediaplayerpl;
        }

        public void SaveMediaPlayerPlaylist(string filename, MediaPlayerPlaylist mpl)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);           
            Serialize(fs, mpl.GetType(), mpl);
            fs.Close();
        }

        #endregion


        #region InGameVars

        public GameVars LoadGameVars(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
        
            _gamevars = (GameVars)(Deserialize(fs,_gamevars.GetType()));
            fs.Close();

            return _gamevars;
        }


        public void SaveGameVars(string filename, GameVars gamevars)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            Serialize(fs,gamevars.GetType(), gamevars);
            fs.Close();

        }




        #endregion

    }
}
